package com.mini.grpc.spring.autoconfigure;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * gRPC服务器配置属性
 * 
 * @author Mini-gRPC
 */
@ConfigurationProperties(prefix = "mini.grpc.server")
public class GrpcServerProperties {
    
    /**
     * 是否启用gRPC服务器
     */
    private boolean enabled = true;
    
    /**
     * 服务器端口
     */
    private int port = 9090;
    
    /**
     * 服务器地址
     */
    private String address = "0.0.0.0";
    
    /**
     * 最大入站消息大小（字节）
     */
    private int maxInboundMessageSize = 4 * 1024 * 1024; // 4MB
    
    /**
     * 最大入站元数据大小（字节）
     */
    private int maxInboundMetadataSize = 8192; // 8KB
    
    /**
     * 握手超时时间（毫秒）
     */
    private long handshakeTimeoutMillis = 120000; // 2分钟
    
    /**
     * 关闭超时时间（秒）
     */
    private long shutdownTimeoutSeconds = 30;
    
    /**
     * 执行器线程数
     */
    private int executorThreads = 0; // 0表示使用默认值
    
    /**
     * 是否启用反射服务
     */
    private boolean reflectionServiceEnabled = false;
    
    /**
     * 是否启用健康检查服务
     */
    private boolean healthServiceEnabled = true;
    
    /**
     * 安全配置
     */
    private Security security = new Security();
    
    /**
     * 网络配置
     */
    private Network network = new Network();
    
    public boolean isEnabled() {
        return enabled;
    }
    
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    
    public int getPort() {
        return port;
    }
    
    public void setPort(int port) {
        this.port = port;
    }
    
    public String getAddress() {
        return address;
    }
    
    public void setAddress(String address) {
        this.address = address;
    }
    
    public int getMaxInboundMessageSize() {
        return maxInboundMessageSize;
    }
    
    public void setMaxInboundMessageSize(int maxInboundMessageSize) {
        this.maxInboundMessageSize = maxInboundMessageSize;
    }
    
    public int getMaxInboundMetadataSize() {
        return maxInboundMetadataSize;
    }
    
    public void setMaxInboundMetadataSize(int maxInboundMetadataSize) {
        this.maxInboundMetadataSize = maxInboundMetadataSize;
    }
    
    public long getHandshakeTimeoutMillis() {
        return handshakeTimeoutMillis;
    }
    
    public void setHandshakeTimeoutMillis(long handshakeTimeoutMillis) {
        this.handshakeTimeoutMillis = handshakeTimeoutMillis;
    }
    
    public long getShutdownTimeoutSeconds() {
        return shutdownTimeoutSeconds;
    }
    
    public void setShutdownTimeoutSeconds(long shutdownTimeoutSeconds) {
        this.shutdownTimeoutSeconds = shutdownTimeoutSeconds;
    }
    
    public int getExecutorThreads() {
        return executorThreads;
    }
    
    public void setExecutorThreads(int executorThreads) {
        this.executorThreads = executorThreads;
    }
    
    public boolean isReflectionServiceEnabled() {
        return reflectionServiceEnabled;
    }
    
    public void setReflectionServiceEnabled(boolean reflectionServiceEnabled) {
        this.reflectionServiceEnabled = reflectionServiceEnabled;
    }
    
    public boolean isHealthServiceEnabled() {
        return healthServiceEnabled;
    }
    
    public void setHealthServiceEnabled(boolean healthServiceEnabled) {
        this.healthServiceEnabled = healthServiceEnabled;
    }
    
    public Security getSecurity() {
        return security;
    }
    
    public void setSecurity(Security security) {
        this.security = security;
    }
    
    public Network getNetwork() {
        return network;
    }
    
    public void setNetwork(Network network) {
        this.network = network;
    }
    
    /**
     * 安全配置
     */
    public static class Security {
        
        /**
         * 是否启用TLS
         */
        private boolean enabled = false;
        
        /**
         * 证书文件路径
         */
        private String certChainFile;
        
        /**
         * 私钥文件路径
         */
        private String privateKeyFile;
        
        /**
         * 信任证书文件路径
         */
        private String trustCertCollectionFile;
        
        /**
         * 客户端认证模式
         */
        private ClientAuth clientAuth = ClientAuth.NONE;
        
        public boolean isEnabled() {
            return enabled;
        }
        
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
        
        public String getCertChainFile() {
            return certChainFile;
        }
        
        public void setCertChainFile(String certChainFile) {
            this.certChainFile = certChainFile;
        }
        
        public String getPrivateKeyFile() {
            return privateKeyFile;
        }
        
        public void setPrivateKeyFile(String privateKeyFile) {
            this.privateKeyFile = privateKeyFile;
        }
        
        public String getTrustCertCollectionFile() {
            return trustCertCollectionFile;
        }
        
        public void setTrustCertCollectionFile(String trustCertCollectionFile) {
            this.trustCertCollectionFile = trustCertCollectionFile;
        }
        
        public ClientAuth getClientAuth() {
            return clientAuth;
        }
        
        public void setClientAuth(ClientAuth clientAuth) {
            this.clientAuth = clientAuth;
        }
        
        public enum ClientAuth {
            NONE, OPTIONAL, REQUIRE
        }
    }
    
    /**
     * 网络配置
     */
    public static class Network {
        
        /**
         * 是否启用keepalive
         */
        private boolean keepAliveEnabled = true;
        
        /**
         * keepalive时间间隔（秒）
         */
        private long keepAliveTimeSeconds = 30;
        
        /**
         * keepalive超时时间（秒）
         */
        private long keepAliveTimeoutSeconds = 5;
        
        /**
         * 是否在没有活跃流时也发送keepalive
         */
        private boolean keepAliveWithoutCalls = false;
        
        /**
         * 最大连接空闲时间（秒）
         */
        private long maxConnectionIdleSeconds = 300; // 5分钟
        
        /**
         * 最大连接年龄（秒）
         */
        private long maxConnectionAgeSeconds = 0; // 0表示无限制
        
        /**
         * 最大连接年龄宽限期（秒）
         */
        private long maxConnectionAgeGraceSeconds = 0; // 0表示无限制
        
        public boolean isKeepAliveEnabled() {
            return keepAliveEnabled;
        }
        
        public void setKeepAliveEnabled(boolean keepAliveEnabled) {
            this.keepAliveEnabled = keepAliveEnabled;
        }
        
        public long getKeepAliveTimeSeconds() {
            return keepAliveTimeSeconds;
        }
        
        public void setKeepAliveTimeSeconds(long keepAliveTimeSeconds) {
            this.keepAliveTimeSeconds = keepAliveTimeSeconds;
        }
        
        public long getKeepAliveTimeoutSeconds() {
            return keepAliveTimeoutSeconds;
        }
        
        public void setKeepAliveTimeoutSeconds(long keepAliveTimeoutSeconds) {
            this.keepAliveTimeoutSeconds = keepAliveTimeoutSeconds;
        }
        
        public boolean isKeepAliveWithoutCalls() {
            return keepAliveWithoutCalls;
        }
        
        public void setKeepAliveWithoutCalls(boolean keepAliveWithoutCalls) {
            this.keepAliveWithoutCalls = keepAliveWithoutCalls;
        }
        
        public long getMaxConnectionIdleSeconds() {
            return maxConnectionIdleSeconds;
        }
        
        public void setMaxConnectionIdleSeconds(long maxConnectionIdleSeconds) {
            this.maxConnectionIdleSeconds = maxConnectionIdleSeconds;
        }
        
        public long getMaxConnectionAgeSeconds() {
            return maxConnectionAgeSeconds;
        }
        
        public void setMaxConnectionAgeSeconds(long maxConnectionAgeSeconds) {
            this.maxConnectionAgeSeconds = maxConnectionAgeSeconds;
        }
        
        public long getMaxConnectionAgeGraceSeconds() {
            return maxConnectionAgeGraceSeconds;
        }
        
        public void setMaxConnectionAgeGraceSeconds(long maxConnectionAgeGraceSeconds) {
            this.maxConnectionAgeGraceSeconds = maxConnectionAgeGraceSeconds;
        }
    }
} 